﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BneyBaruch.Ingest.MorningLesson.Services;
using BneyBaruch.Ingest.MorningLesson.Services.Data;
using System.ServiceModel;
using System.Workflow.Runtime;
using BneyBaruch.Ingest.MorningLesson.WorkflowCommunication.RecordingController;
using System.Threading;
using BneyBaruch.Ingest.MorningLesson.Workflow;
using BneyBaruch.Ingest.Core.WorkflowCommunication.Extensions;
using System.Workflow.Activities;
using BneyBaruch.Ingest.MorningLesson.WorkflowCommunication.VideoCaptureBoxServer;

namespace BneyBaruch.Ingest.MorningLesson.WorkflowProcessor.Services
{
    [ServiceBehavior
        (
            InstanceContextMode = InstanceContextMode.Single,
            ConcurrencyMode = ConcurrencyMode.Reentrant
        )
    ]
    public class MorningLessonWorkflowProcessor : IMorningLessonWorkflowProcessor,IDisposable
    {
        #region Fields

        private WorkflowRuntime workflowRuntime;
        private RecordingControllerExchangeService recordingControllerExchangeService;
        private VideoCaptureBoxServerExchangeService videoCaptureBoxServerExchangeService;

        #endregion

        #region IMorningLessonWorkflowProcessor Members

        public StartMorningLessonResponse StartMorningLesson(StartMorningLessonRequest startMorningLessonRequest)
        {
            SetUpWorkflowEnvironment();

            // Create a new instance of the SequentialWorkflow and submit it to the WorkflowRuntime
            Guid workflowInstanceId = startMorningLessonRequest.WorkflowInstanceId;

            WorkflowInstance workflowInstance =
                workflowRuntime.CreateWorkflow(typeof(MorningLessonWorkflow), null, workflowInstanceId);
            workflowInstance.Start();

            return new StartMorningLessonResponse()
            {
                WorkflowInstanceId = workflowInstanceId
            };
        }

        #endregion

        #region Private Workflow Methods

        /// <summary>
        /// Ensures that the instance of RecordingControllerExchangeService,VideoCaptureBoxServerExchangeService and other exchange services
        /// has been initialized and added to the workflow's data exchange service to enable workflow and workflow host communication.
        /// </summary>
        /// <remarks>
        /// There will only be a single instance of this object in activation
        /// at any point in time.
        /// </remarks>
        private void SetUpWorkflowEnvironment()
        {
            #region Register recording controller exchange service

            if (recordingControllerExchangeService == null)
            {
                WorkflowRuntimePerServiceContainer extension =
                    OperationContext.Current.Host.Extensions.Find<WorkflowRuntimePerServiceContainer>();

                workflowRuntime = extension.WorkflowRuntime;

                // We will try and fetch the instance from the active WorkflowRuntime's
                // ExtenalDataExchangeService and if it currently does not have an
                // activated instance, we will create a new instance and add it.
                ExternalDataExchangeService dataExchangeService =
                    workflowRuntime.GetService<ExternalDataExchangeService>();

                recordingControllerExchangeService =
                    (RecordingControllerExchangeService)dataExchangeService.GetService(typeof(RecordingControllerExchangeService));

                if (recordingControllerExchangeService == null)
                {
                    recordingControllerExchangeService = new RecordingControllerExchangeService(workflowRuntime);
                    dataExchangeService.AddService(recordingControllerExchangeService);
                }
            }

            #endregion

            #region Register video capture box servers exchange service

            if (videoCaptureBoxServerExchangeService == null)
            {
                WorkflowRuntimePerServiceContainer extension =
                    OperationContext.Current.Host.Extensions.Find<WorkflowRuntimePerServiceContainer>();

                workflowRuntime = extension.WorkflowRuntime;

                // We will try and fetch the instance from the active WorkflowRuntime's
                // ExtenalDataExchangeService and if it currently does not have an
                // activated instance, we will create a new instance and add it.
                ExternalDataExchangeService dataExchangeService =
                    workflowRuntime.GetService<ExternalDataExchangeService>();


                videoCaptureBoxServerExchangeService =
                    (VideoCaptureBoxServerExchangeService)dataExchangeService.GetService(typeof(VideoCaptureBoxServerExchangeService));

                if (videoCaptureBoxServerExchangeService == null)
                {
                    videoCaptureBoxServerExchangeService = new VideoCaptureBoxServerExchangeService(workflowRuntime);
                    dataExchangeService.AddService(videoCaptureBoxServerExchangeService);
                }
            }

            #endregion
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            if (recordingControllerExchangeService != null)
                recordingControllerExchangeService.Dispose();

            if (videoCaptureBoxServerExchangeService != null)
                videoCaptureBoxServerExchangeService.Dispose();
        }

        #endregion
    }
}
